home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / pppcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  20.7 KB  |  838 lines

  1. /*
  2.  *  PPPCMD.C    -- PPP related user commands
  3.  *
  4.  *    12-89    -- Katie Stevens (dkstevens@ucdavis.edu)
  5.  *           UC Davis, Computing Services
  6.  *    PPP.07    04-90    [ks] new storage for peer addr for IPCP
  7.  *    PPP.08  05-90    [ks] improve PPP trace reporting
  8.  *    PPP.09    05-90    [ks] add commands to set PPP Auth protocol
  9.  *                 (UPAP server) and UPAP peerID (UPAP client)
  10.  *    PPP.10    6-90    [ks] improve keybd input of UPAP password
  11.  *                 make ppp open/close/reset work properly
  12.  *                 add peer IP lookup pool
  13.  *    PPP.13    8-90    [ks] report PPP open timestamp with stats
  14.  *    PPP.14    8-90    [ks] change UPAP to PAP for consistency with RFC1172
  15.  *                 add RLSD physical link up/down handling
  16.  *                 add autobaud handling to set link speed
  17.  *                 make LCP/IPCP timeout configurable
  18.  *    PPP.15    09-90    [ks] update to KA9Q NOS v900828
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <time.h>
  23. #include "global.h"
  24. #include "mbuf.h"
  25. #include "iface.h"
  26. #include "timer.h"
  27. #include "asy.h"
  28. #include "slcompre.h"
  29. #include "ppp.h"
  30. #include "slip.h"
  31. #include "commands.h"
  32. #include "netuser.h"
  33. /*#include "internet.h"*/
  34. #include "cmdparse.h"
  35. #include "config.h"
  36.  
  37. extern char Badhost[];
  38.  
  39. int16 ppptrace = 0;
  40. int16 Npool = 0;        /* Number of pools for PPP interfaces */
  41.  
  42. #ifdef notdef /*MUXASY*/
  43. struct ipcppool PPPpool[ASY_MAX*PORTS_PER_MUX];    /* For pooling peer IP addrs */
  44. #else
  45. struct ipcppool PPPpool[ASY_MAX];        /* For pooling peer IP addrs */
  46. #endif
  47.  
  48. static int dopppaccomp __ARGS((int argc, char *argv[], void *p));
  49. static int dopppactive __ARGS((int argc, char *argv[], void *p));
  50. static int dopppauth __ARGS((int argc, char *argv[], void *p));
  51. static int dopppclose __ARGS((int argc, char *argv[], void *p));
  52. static int dopppctlmap __ARGS((int argc, char *argv[], void *p));
  53. static int dopppmru __ARGS((int argc, char *argv[], void *p));
  54. static int dopppipcomp __ARGS((int argc, char *argv[], void *p));
  55. static int doppppassive __ARGS((int argc, char *argv[], void *p));
  56. static int doppppeer __ARGS((int argc, char *argv[], void *p));
  57. static int doppppool __ARGS((int argc, char *argv[], void *p));
  58. static int dopppprotcomp __ARGS((int argc, char *argv[], void *p));
  59. static int dopppreset __ARGS((int argc, char *argv[], void *p));
  60. static int dopppstat __ARGS((int argc, char *argv[], void *p));
  61. static int doppptrace __ARGS((int argc, char *argv[], void *p));
  62. static int doppptimeout __ARGS((int argc, char *argv[], void *p));
  63. static int dopapuser __ARGS((int argc, char *argv[], void *p));
  64.  
  65. static void genstat __ARGS((struct slip *sp));
  66. static void pppstat __ARGS((struct slip *sp));
  67. static void lcpstat __ARGS((struct lcpctl *lcpiop));
  68. static void ipcpstat __ARGS((struct ipcpctl *ipcpiop));
  69. static struct iface *ppplookup __ARGS((char *ifname));
  70. static void dumppool __ARGS(());
  71. static char *uptime __ARGS((long first, long second));
  72.  
  73. /* "ppp" subcommands */
  74. static struct cmds Pppcmds[] = {
  75.     "accompr",    dopppaccomp,    0,    2,
  76.         "ppp accompr <iface> <int>",
  77.     "activeopen",    dopppactive,    0,    2,
  78.         "ppp activeopen <iface>",
  79.     "authprot",    dopppauth,    0,    2,
  80.         "ppp authprot <authtype>",
  81.     "close",    dopppclose,    0,    2,
  82.         "ppp close <iface>",
  83.     "ctlmap",    dopppctlmap,    0,    2,
  84.         "ppp ctlmap <iface> <int>",
  85.     "ipcompr",    dopppipcomp,    0,    2,
  86.         "ppp ipcompr <iface> <comprtype>",
  87.     "mru",        dopppmru,    0,    2,
  88.         "ppp mru <iface> <int>",
  89.     "passiveopen",    doppppassive,    0,    2,
  90.         "ppp passiveopen <iface>",
  91.     "peeraddr",    doppppeer,    0,    2,
  92.         "ppp peeraddr <iface> <addr>",
  93.     "peerid",    dopapuser,    0,    2,
  94.         "ppp peerid <iface> <peer ID code>",
  95.     "pooladdr",    doppppool,    0,    1,
  96.         "ppp pooladdr <addr>:<# addr in pool> [ <iface> ... ]",
  97.     "protcompr",    dopppprotcomp,    0,    2,
  98.         "ppp protcompr <iface> <int>",
  99.     "reset",    dopppreset,    0,    2,
  100.         "ppp reset <iface>",
  101.     "status",    dopppstat,    0,    0,    NULLCHAR,
  102.     "timeout",    doppptimeout,    0,    2,
  103.         "ppp timeout <iface> <#sec>",
  104.     "trace",    doppptrace,    0,    0,    NULLCHAR,
  105.     NULLCHAR,
  106. };
  107.  
  108. static char *PPPStatus[] = {
  109.     "physical layer down",
  110.     "waiting for link speed assignment message",
  111.     "Closed",
  112.     "waiting for LCP negotiation",
  113.     "waiting for PAP verfication",
  114.     "waiting for IPCP negotiation",
  115.     "Open"
  116. };
  117. static char *LCPStatus[] = {
  118.     "Closed",
  119.     "Listen; waiting for remote host to attempt open",
  120.     "Req Sent: Attempting to start configuration exchange",
  121.     "Ack Rcvd: Remote host accepted our request; waiting for remote request",
  122.     "Ack Sent: Waiting for reply to our request; accepted remote request",
  123.     "Open; configuration negotiation complete",
  124.     "Terminate request sent to remote host"
  125. };
  126.  
  127. /****************************************************************************/
  128.  
  129. int
  130. dopppcontrol(argc,argv,p)
  131. int argc;
  132. char *argv[];
  133. void *p;
  134. {
  135.     return subcmd(Pppcmds,argc,argv,p);
  136. }
  137.  
  138. /****************************************************************************/
  139.  
  140. /* Initiate active open on a PPP interface */
  141. static int
  142. dopppactive(argc,argv,p)
  143. int argc;
  144. char *argv[];
  145. void *p;
  146. {
  147.     struct iface *ifp;
  148.     struct pppctl *pppiop;
  149.     struct lcpctl *lcpiop;
  150.  
  151.     /* Look for the PPP interface */
  152.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  153.         return -1;
  154.  
  155.     /* Start LCP configuration negotiation on interface */
  156.     pppiop = Slip[ifp->xdev].pppio;
  157.     lcpiop = &(pppiop->lcpio);
  158.     lcpiop->active = 1;
  159.     if ((pppiop->state == PPP_PL_DOWN) || (pppiop->state == PPP_AUTOBAUD))
  160.         return 0;
  161.     else
  162.         return(lcp_start(&Slip[ifp->xdev]));
  163. }
  164.  
  165. /* Close connection on PPP interface */
  166. static int
  167. dopppclose(argc,argv,p)
  168. int argc;
  169. char *argv[];
  170. void *p;
  171. {
  172.     struct iface *ifp;
  173.  
  174.     /* Look for the PPP interface */
  175.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  176.         return -1;
  177.  
  178.     /* Close PPP connection */
  179.     return(ppp_close(&Slip[ifp->xdev],1));
  180. }
  181.  
  182. /* Set PPP interface to passive open; will revert to LISTEN on next close */
  183. static int
  184. doppppassive(argc,argv,p)
  185. int argc;
  186. char *argv[];
  187. void *p;
  188. {
  189.     struct iface *ifp;
  190.     struct pppctl *pppiop;
  191.     struct lcpctl *lcpiop;
  192.  
  193.     /* Look for the PPP interface */
  194.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  195.         return -1;
  196.  
  197.     /* Start LCP configuration negotiation on interface */
  198.     pppiop = Slip[ifp->xdev].pppio;
  199.     lcpiop = &(pppiop->lcpio);
  200.     lcpiop->active = 0;
  201.     return 0;
  202. }
  203.  
  204. /* Close and reopen connection on PPP interface */
  205. static int
  206. dopppreset(argc,argv,p)
  207. int argc;
  208. char *argv[];
  209. void *p;
  210. {
  211.     struct iface *ifp;
  212.     struct slip *sp;
  213.     struct pppctl *pp;
  214.     struct slcompress *slp;
  215.  
  216.     /* Look for the PPP interface */
  217.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  218.         return -1;
  219.     sp = &Slip[ifp->xdev];
  220.     pp = sp->pppio;
  221.  
  222.     /* Close PPP connection */
  223.     ppp_close(&Slip[ifp->xdev],0);
  224.  
  225. #ifndef PPP_NO_STATS
  226.     /* Zero PPP packet counters */
  227.     pp->sndpkt = 0L;        /* # packets sent on PPP interface */
  228.     pp->snderr = 0;            /* # pkts with PPP error on send */
  229.     pp->rcvpkt = 0L;        /* # packets rcvd on PPP interface */
  230.     pp->rcverr = 0;            /* # pkts with error */
  231.     pp->csumerr = 0;        /* # rcv pkts with bad PPP checksum */
  232.  
  233.     pp->sndlcp = 0;            /* # LCP packets sent */
  234.     pp->sndpap = 0;            /* # PAP packets sent */
  235.     pp->sndipcp = 0;        /* # IPCP packets sent */
  236.     pp->sndip = 0L;            /* # IP packets sent */
  237.     pp->rcvlcp = 0;            /* # LCP packets received */
  238.     pp->rcvpap = 0;            /* # PAP packets received */
  239.     pp->rcvipcp = 0;        /* # IPCP packets received */
  240.     pp->rcvip = 0L;            /* # IP packets received */
  241.     pp->rcvunk = 0;            /* # unknown packets received */
  242. #endif
  243.  
  244. #ifndef SL_NO_STATS
  245.     slp = sp->slcomp;
  246.     slp->sls_nontcp = 0L;        /* outbound non-TCP packets */
  247.     slp->sls_asistcp = 0L;        /* outbound TCP packets */
  248.     slp->sls_compressed = 0L;    /* outbound compressed packets */
  249.     slp->sls_uncompressed = 0L;    /* outbound uncompressed packets */
  250.     slp->sls_searches = 0L;        /* searches for connection state */
  251.     slp->sls_misses = 0L;        /* times couldn't find conn. state */
  252.     slp->sls_nontcpin = 0L;        /* inbound non-TCP packets */
  253.     slp->sls_tcpin = 0L;        /* inbound TCP packets */
  254.     slp->sls_uncompressedin = 0L;    /* inbound uncompressed packets */
  255.     slp->sls_compressedin = 0L;    /* inbound compressed packets */
  256.     slp->sls_errorin = 0L;        /* inbound unknown type packets */
  257.     slp->sls_tossed = 0L;        /* inbound tossed because of error */
  258. #endif
  259.  
  260.     /* Always restart as active open when PPP reset */
  261.     pp->lcpio.active = 1;
  262.     tprintf("Attempting to reopen PPP interface  %s\n",ifp->name);
  263.     return(lcp_start(&Slip[ifp->xdev]));
  264. }
  265.  
  266. /*******************************************/
  267.  
  268. /* Set Address/Control Compression for a PPP interface */
  269. static int
  270. dopppaccomp(argc,argv,p)
  271. int argc;
  272. char *argv[];
  273. void *p;
  274. {
  275.     struct iface *ifp;
  276.     struct pppctl *pppiop;
  277.     struct lcpctl *lcpiop;
  278.     struct lcpparm *localp;
  279.  
  280.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  281.         return -1;
  282.     --argc;++argv;
  283.  
  284.     pppiop = Slip[ifp->xdev].pppio;
  285.     lcpiop = &(pppiop->lcpio);
  286.     localp = &(lcpiop->initparm);
  287.     localp->neg_ac_compress = 1;
  288.     return setbool(&(localp->ac_compress),
  289.             "Addr/Ctl Field Compression",argc,argv);
  290. }
  291.  
  292. /* Set authentication type for PPP interface */
  293. static int
  294. dopppauth(argc,argv,p)
  295. int argc;
  296. char *argv[];
  297. void *p;
  298. {
  299.     struct iface *ifp;
  300.     struct pppctl *pppiop;
  301.     struct lcpctl *lcpiop;
  302.     struct lcpparm *localp;
  303.  
  304.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  305.         return -1;
  306.  
  307.     pppiop = Slip[ifp->xdev].pppio;
  308.     lcpiop = &(pppiop->lcpio);
  309.     localp = &(lcpiop->initparm);
  310.     if (argc < 3) {
  311.         tprintf("%s\n",((localp->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"));
  312.     } else if ((strnicmp("pap",argv[2],2) == 0)
  313.             || ((int16)strtol(argv[2],NULLCHARP,0)==PAP_AUTH_TYPE)) {
  314.         localp->neg_auth_type = 1;
  315.         localp->auth_type = PAP_AUTH_TYPE;
  316.     } else if ((stricmp("none",argv[2]) == 0)
  317.             || ((int16)strtol(argv[2],NULLCHARP,0) == 0)) {
  318.         localp->neg_auth_type = 0;
  319.         localp->auth_type = DEF_AUTH_TYPE;
  320.     } else {
  321.         tprintf("unknown Authentication Protocol type; command ignored\n");
  322.         return 1;
  323.     }
  324.     return 0;
  325. }
  326.  
  327. /* Set Async Control Map for a PPP interface */
  328. static int
  329. dopppctlmap(argc,argv,p)
  330. int argc;
  331. char *argv[];
  332. void *p;
  333. {
  334.     long lx;
  335.     struct iface *ifp;
  336.     struct pppctl *pppiop;
  337.     struct lcpctl *lcpiop;
  338.     struct lcpparm *localp;
  339.  
  340.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  341.         return -1;
  342.  
  343.     pppiop = Slip[ifp->xdev].pppio;
  344.     lcpiop = &(pppiop->lcpio);
  345.     localp = &(lcpiop->initparm);
  346.     if (argc < 3) {
  347.         tprintf("0x%08lx\n",localp->ctl_map);
  348.     } else {
  349.         lx = strtol(argv[2], NULLCHARP, 0);
  350.         localp->neg_ctl_map = 1;
  351.         localp->ctl_map = lx;
  352.     }
  353.     return 0;
  354. }
  355.  
  356. /* Set preferred Maximum Receive Unit for a PPP interface */
  357. static int
  358. dopppmru(argc,argv,p)
  359. int argc;
  360. char *argv[];
  361. void *p;
  362. {
  363.     int x;
  364.     struct iface *ifp;
  365.     struct pppctl *pppiop;
  366.     struct lcpctl *lcpiop;
  367.     struct lcpparm *localp;
  368.  
  369.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  370.         return -1;
  371.  
  372.     pppiop = Slip[ifp->xdev].pppio;
  373.     lcpiop = &(pppiop->lcpio);
  374.     localp = &(lcpiop->initparm);
  375.     if (argc < 3) {
  376.         tprintf("%d\n",localp->mru);
  377.     } else {
  378.         x = atoi(argv[2]);
  379.         if ((x < MIN_MRU)||(x > DEF_MRU)) {
  380.             tprintf("Command rejected; MRU out of range: Min MRU: %d  Max MRU: %d\n",
  381.                 MIN_MRU,DEF_MRU);
  382.             return -1;
  383.         } else {
  384.             localp->neg_mru = 1;
  385.             localp->mru = x;
  386.         }
  387.     }
  388.     return 0;
  389. }
  390.  
  391. /* Set Protocol Compression for a PPP interface */
  392. static int
  393. dopppprotcomp(argc,argv,p)
  394. int argc;
  395. char *argv[];
  396. void *p;
  397. {
  398.     struct iface *ifp;
  399.     struct pppctl *pppiop;
  400.     struct lcpctl *lcpiop;
  401.     struct lcpparm *localp;
  402.  
  403.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  404.         return -1;
  405.     --argc;++argv;
  406.  
  407.     pppiop = Slip[ifp->xdev].pppio;
  408.     lcpiop = &(pppiop->lcpio);
  409.     localp = &(lcpiop->initparm);
  410.     localp->neg_prot_compress = 1;
  411.     return setbool(&(localp->prot_compress),
  412.             "Protocol Field Compression",argc,argv);
  413. }
  414.  
  415. /* Set timeout interval when waiting for response from remote peer */
  416. static int
  417. doppptimeout(argc,argv,p)
  418. int argc;
  419. char *argv[];
  420. void *p;
  421. {
  422.     int x;
  423.     struct iface *ifp;
  424.     struct pppctl *pppiop;
  425.     struct lcpctl *lcpiop;
  426.     struct ipcpctl *ipcpiop;
  427.     struct timer *t;
  428.  
  429.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  430.         return -1;
  431.  
  432.     pppiop = Slip[ifp->xdev].pppio;
  433.     lcpiop = &(pppiop->lcpio);
  434.     t = &(lcpiop->lcp_tm);
  435.     if (argc < 3) {
  436.         tprintf("%d\n",(t->start/(1000L/MSPTICK)));
  437.     } else {
  438.         x = atoi(argv[2]);
  439.         if (x <= 0) {
  440.             tprintf("Command rejected; timeout value must be > 0\n");
  441.             return -1;
  442.         } else {
  443.             t->start = x*(1000L/MSPTICK);
  444.             ipcpiop = &(pppiop->ipcpio);
  445.             t = &(ipcpiop->ipcp_tm);
  446.             t->start = x*(1000L/MSPTICK);
  447.         }
  448.     }
  449.     return 0;
  450. }
  451.  
  452. /* Set peer ID string to send with PAP AUTH_REQ */
  453. static int
  454. dopapuser(argc,argv,p)
  455. int argc;
  456. char *argv[];
  457. void *p;
  458. {
  459.     struct iface *ifp;
  460.     struct pppctl *pppiop;
  461.     struct lcpctl *lcpiop;
  462.  
  463.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  464.         return -1;
  465.  
  466.     pppiop = Slip[ifp->xdev].pppio;
  467.     lcpiop = &(pppiop->lcpio);
  468.     if (argc < 3) {
  469.         tprintf("%s\n",((lcpiop->pap_user==NULLCHAR)?"None":lcpiop->pap_user));
  470.     } else if (strnicmp("none",argv[2],2) == 0) {
  471.         if (lcpiop->pap_user != NULLCHAR)
  472.             free(lcpiop->pap_user);
  473.     } else {
  474.         if (lcpiop->pap_user != NULLCHAR)
  475.             free(lcpiop->pap_user);
  476.         if (lcpiop->pap_pass != NULLCHAR)
  477.             free(lcpiop->pap_pass);
  478.         lcpiop->pap_user = mallocw(strlen(argv[2])+1);
  479.         strcpy(lcpiop->pap_user,argv[2]);
  480.         pap_getpass(&Slip[ifp->xdev],0);
  481.     }
  482.     return 0;
  483. }
  484.  
  485. /*******************************************/
  486.  
  487. /* Set IP compression type for PPP interface */
  488. static int
  489. dopppipcomp(argc,argv,p)
  490. int argc;
  491. char *argv[];
  492. void *p;
  493. {
  494.     struct iface *ifp;
  495.     struct pppctl *pppiop;
  496.     struct ipcpctl *ipcpiop;
  497.  
  498.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  499.         return -1;
  500.  
  501.     pppiop = Slip[ifp->xdev].pppio;
  502.     ipcpiop = &(pppiop->ipcpio);
  503.     if (argc < 3) {
  504.         if (ipcpiop->ip_compr_type == IPCP_VJCOMPR)
  505.             tprintf("Van Jacobson TCP header compression enabled\n");
  506.         else
  507.             tprintf("IP compression disabled\n");
  508.     } else if ((strnicmp("vj",argv[2],2) == 0)
  509.             || ((int16)strtol(argv[2],NULLCHARP,0) == IPCP_VJCOMPR)) {
  510.         ipcpiop->neg_ip_compr = 1;
  511.         ipcpiop->ip_compr_type = IPCP_VJCOMPR;
  512.     } else if ((int16)strtol(argv[2],NULLCHARP,0) == 0) {
  513.         ipcpiop->neg_ip_compr = 1;
  514.         ipcpiop->ip_compr_type = 0;
  515.     } else {
  516.         tprintf("unknown IP compression type; command ignored\n");
  517.         return 1;
  518.     }
  519.     return 0;
  520. }
  521.  
  522. /* Set peer address for PPP interface */
  523. static int
  524. doppppeer(argc,argv,p)
  525. int argc;
  526. char *argv[];
  527. void *p;
  528. {
  529.     int32 x32;
  530.     struct iface *ifp;
  531.     struct pppctl *pppiop;
  532.     struct ipcpctl *ipcpiop;
  533.  
  534.     if ((ifp = ppplookup(argv[1])) == NULLIF)
  535.         return -1;
  536.  
  537.     pppiop = Slip[ifp->xdev].pppio;
  538.     ipcpiop = &(pppiop->ipcpio);
  539.     if (argc < 3) {
  540.         tprintf("%s\n",inet_ntoa(ipcpiop->peer_addr));
  541.     } else if ((x32 = resolve(argv[2])) == 0L) {
  542.         tprintf(Badhost,argv[2]);
  543.         return 1;
  544.     } else {
  545.         ipcpiop->peer_addr = x32;
  546.     }
  547.     return 0;
  548. }
  549.  
  550. /* Set a pool of peer addresses for PPP interface */
  551. static int
  552. doppppool(argc,argv,p)
  553. int argc;
  554. char *argv[];
  555. void *p;
  556. {
  557.     int pool;
  558.     int pool_cnt;
  559.     char *bitp;
  560.     int32 pool_addr;
  561.     struct ipcppool *poolp;
  562.     struct iface *ifp;
  563.     struct pppctl *pppiop;
  564.  
  565.     if (argc < 2) {
  566.         dumppool();
  567.         return 0;
  568.     }
  569.  
  570.     if (Npool > ASY_MAX) {
  571.         tprintf("Too many PPP address pools -- command rejected\n");
  572.         return -1;
  573.     }
  574.  
  575.     /* Need at least one IP address for the pool */
  576.     if((pool_addr = resolve(argv[1])) == 0){
  577.         tprintf("Must specify an IP address pool\n");
  578.         return -1;
  579.     }
  580.     /* May specify a consecutive range of addresses; otherwise assume 1 */
  581.     if((bitp = strchr(argv[1],':')) != NULLCHAR){
  582.         bitp++;
  583.         pool_cnt = atoi(bitp);
  584.     } else
  585.         pool_cnt = 1;
  586.     if (pool_cnt < 0) {
  587.         tprintf("Unreasonable address range  --  command rejected\n");
  588.         return -1;
  589.     }
  590.  
  591.     if (argc < 3) {
  592.         printf("Must specify a PPP interface\n");
  593.         return -1;
  594.     }
  595.  
  596.     pool = Npool++;
  597.     poolp = &(PPPpool[pool]);
  598.     poolp->peer_min = pool_addr;
  599.     poolp->peer_max = pool_addr + pool_cnt - 1;
  600.     poolp->peer_next = pool_addr;
  601.  
  602.     argc -= 2;argv++;
  603.     while (argc--) {
  604.         argv++;
  605.         if ((ifp = ppplookup(*argv)) == NULLIF)
  606.             continue;
  607.         pppiop = Slip[ifp->xdev].pppio;
  608.         pppiop->ipcpio.peer_pool = &(PPPpool[pool]);
  609.     }
  610.     return 0;
  611. }
  612.  
  613. /****************************************************************************/
  614.  
  615. static int
  616. doppptrace(argc,argv,p)
  617. int argc;
  618. char *argv[];
  619. void *p;
  620. {
  621.     return setshort(&ppptrace,"PPP tracing",argc,argv);
  622. }
  623.  
  624. /****************************************************************************/
  625.  
  626. static int
  627. dopppstat(argc,argv,p)
  628. int argc;
  629. char *argv[];
  630. void *p;
  631. {
  632.     register struct slip *sp;
  633.     struct iface *ifp;
  634.  
  635.     if (argc < 2) {
  636.         for (sp = Slip;sp < &Slip[Nasy];sp++) {
  637.             if (sp->type != TYPE_PPP)
  638.                 continue;
  639.             genstat(sp);
  640.         }
  641.     } else {
  642.         if ((ifp = ppplookup(argv[1])) == NULLIF)
  643.             return -1;
  644.         sp = &Slip[ifp->xdev];
  645.         genstat(sp);
  646.         pppstat(sp);
  647.         lcpstat(&(sp->pppio->lcpio));
  648.         ipcpstat(&(sp->pppio->ipcpio));
  649.     }
  650.     return 0;
  651. }
  652.  
  653. static void
  654. genstat(sp)
  655. struct slip *sp;
  656. {
  657.     register struct pppctl *pp;
  658.  
  659.     pp = sp->pppio;
  660.     tprintf("%s:\t",sp->iface->name);
  661.     tprintf("SndPkt: %ld  SndErr: %d  RcvPkt: %ld  RcvErr: %d  ChksumErr: %d\n",
  662.         pp->sndpkt,pp->snderr,pp->rcvpkt,pp->rcverr,pp->csumerr);
  663.     return;
  664. }
  665.  
  666. static void
  667. pppstat(sp)
  668. struct slip *sp;
  669. {
  670.     register struct pppctl *pp;
  671.     register struct slcompress *scp;
  672.  
  673.     pp = sp->pppio;
  674.     scp = sp->slcomp;
  675.     tprintf("\tOverall PPP state: %s",
  676.         PPPStatus[pp->state]);
  677.     if (pp->state == PPP_OPEN) {
  678.         tprintf("   (open for %s)\n",uptime(pp->upsince,time(0L)));
  679.     } else {
  680.         tprintf("\n");
  681.     }
  682.     tprintf("\t    SndIP: %ld  SndLCP: %d  SndPAP: %d  SndIPCP: %d\n",
  683.         pp->sndip,pp->sndlcp,pp->sndpap,pp->sndipcp);
  684.     if (sp->escaped & PPP_XMT_VJCOMPR) {
  685.         tprintf("\t      (IP) NotTCP: %ld  AsIsTCP: %ld  CmpTCP: %ld  UncmpTCP: %ld\n",
  686.             scp->sls_nontcp,scp->sls_asistcp,scp->sls_compressed,scp->sls_uncompressed);
  687.     }
  688.     tprintf("\t    RcvIP: %ld  RcvLCP: %d  RcvPAP: %d  RcvIPCP: %d  RcvUnknown: %d\n",
  689.         pp->rcvip,pp->rcvlcp,pp->rcvpap,pp->rcvipcp,pp->rcvunk);
  690.     if (sp->escaped & PPP_RCV_VJCOMPR) {
  691.         tprintf("\t      (IP) NotTCP: %ld  AsIsTCP: %ld  CmpTCP: %ld  UncmpTCP: %ld\n",
  692.             scp->sls_nontcpin,scp->sls_tcpin,scp->sls_compressedin,scp->sls_uncompressedin);
  693.         tprintf("\t           Unknown: %ld  CmpError: %ld\n",
  694.             scp->sls_errorin,scp->sls_tossed);
  695.     }
  696.     return;
  697. }
  698.  
  699. static void
  700. lcpstat(lcpiop)
  701. struct lcpctl *lcpiop;
  702. {
  703.     struct lcpparm *localp, *remotep;
  704.  
  705.     localp = &(lcpiop->lclparm);
  706.     remotep = &(lcpiop->remparm);
  707.  
  708.     tprintf("\tLCP state: %s\n",LCPStatus[lcpiop->lcp_state]);
  709.     tprintf("\t\t\t\tLocal options\tRemote options\n");
  710.     tprintf("\t    MRU:\t\t%d\t\t%d\n",
  711.         localp->mru,remotep->mru);
  712.     tprintf("\t    Ctl Map:\t\t0x%08lx\t0x%08lx\n",
  713.         localp->ctl_map,remotep->ctl_map);
  714.     tprintf("\t    Auth Prot:\t\t%s\t\t%s\n",
  715.         ((localp->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"),
  716.         ((remotep->auth_type == PAP_AUTH_TYPE) ? "PAP" : "None"));
  717.     tprintf("\t    Protocol Compr:\t%s\t\t%s\n",
  718.         (localp->prot_compress ? "ON" : "OFF"),
  719.         (remotep->prot_compress ? "ON" : "OFF"));
  720.     tprintf("\t    Addr/Ctl Compr:\t%s\t\t%s\n",
  721.         (localp->ac_compress ? "ON" : "OFF"),
  722.         (remotep->ac_compress ? "ON" : "OFF"));
  723. }
  724.  
  725. static void
  726. ipcpstat(ipcpiop)
  727. struct ipcpctl *ipcpiop;
  728. {
  729.     tprintf("\tIPCP state: %s\n",LCPStatus[ipcpiop->ipcp_state]);
  730.     tprintf("\t    IPCP local IP address:\t%s\n",
  731.         inet_ntoa(ipcpiop->attempt_src));
  732.     tprintf("\t    IPCP remote IP address:\t%s\n",
  733.         inet_ntoa(ipcpiop->attempt_dest));
  734.     if (ipcpiop->lcl_ip_compr == IPCP_VJCOMPR)
  735.         tprintf("\t    Rcv: Van Jacobson TCP header compression enabled\n");
  736.     else
  737.         tprintf("\t    Rcv: IP compression disabled\n");
  738.     if (ipcpiop->rem_ip_compr == IPCP_VJCOMPR)
  739.         tprintf("\t    Snd: Van Jacobson TCP header compression enabled\n");
  740.     else
  741.         tprintf("\t    Snd: IP compression disabled\n");
  742.  
  743.     return;
  744. }
  745.  
  746. /****************************************************************************/
  747.  
  748. static void
  749. dumppool()
  750. {
  751.     struct iface *ifp;
  752.     struct pppctl *pppiop;
  753.     struct ipcppool *poolp;
  754.  
  755.     tprintf("Interface        Pool Base/Count\tNext Address\n");
  756.     for (ifp=Ifaces; ifp != NULLIF; ifp = ifp->next) {
  757.         if ((Slip[ifp->xdev].iface == ifp) &&
  758.             (Slip[ifp->xdev].type == TYPE_PPP)) {
  759.             pppiop = Slip[ifp->xdev].pppio;
  760.             poolp = pppiop->ipcpio.peer_pool;
  761.             if (poolp == NULLPOOL)
  762.                 continue;
  763.             tprintf("%-11s%19s/%-2d",
  764.                 ifp->name,inet_ntoa(poolp->peer_min),
  765.                 (poolp->peer_max - poolp->peer_min + 1));
  766.             tprintf("\t%s\n",inet_ntoa(poolp->peer_next));
  767.         }
  768.     }
  769.     return;
  770. }
  771.  
  772. static struct iface *
  773. ppplookup(ifname)
  774. char *ifname;
  775. {
  776.     struct iface *ifp;
  777.  
  778.     for (ifp=Ifaces;ifp != NULLIF;ifp = ifp->next) {
  779.         if (!strcmp(ifname,ifp->name))
  780.             break;
  781.     }
  782.     if (ifp == NULLIF) {
  783.         tprintf(Badinterface,ifname);
  784.         return(NULLIF);
  785.     } else if (ifp->type != TYPE_PPP) {
  786.         tprintf("Interface %s not a PPP interface\n",ifp->name);
  787.         return(NULLIF);
  788.     } else {
  789.         return(ifp);
  790.     }
  791. }
  792.  
  793.  
  794. /* Break a time differential, measured in seconds, into weeks, days      */
  795. /* hours, minutes, and seconds. Store ASCII description in static buffer */
  796. #define SECS_MIN    60L
  797. #define SECS_HR        3600L
  798. #define SECS_DAY    86400L
  799. #define SECS_WEEK    604800L
  800.  
  801. static char utbuf[128];
  802.  
  803. static char *
  804. uptime(first, second)
  805. long first;
  806. long second;
  807. {
  808.     int found = 0;
  809.     long diff;
  810.     long part;
  811.  
  812.     utbuf[0] = '\0';
  813.     diff = second - first;
  814.     if ((diff > SECS_DAY)||(found)) {
  815.         part = diff / SECS_DAY;
  816.         sprintf(&(utbuf[strlen(utbuf)]),
  817.             "%ld day%s ",part,((part==1)?",":"s,"));
  818.         diff -= (part * SECS_DAY);
  819.         found = 100;
  820.     }
  821.     if ((diff > SECS_HR)||(found)) {
  822.         part = diff / SECS_HR;
  823.         sprintf(&(utbuf[strlen(utbuf)]),
  824.             "%ld hr%s ",part,((part==1)?",":"s,"));
  825.         diff -= (part * SECS_HR);
  826.         ++found;
  827.     }
  828.     if ((diff > SECS_MIN)||(found)) {
  829.         part = diff / SECS_MIN;
  830.         sprintf(&(utbuf[strlen(utbuf)]),"%ld mi%s",part,
  831.             ((found < 100)?"n, ":"n"));
  832.         diff -= (part * SECS_MIN);
  833.     }
  834.     if (found < 100)
  835.         sprintf(&(utbuf[strlen(utbuf)]),"%ld sec",diff);
  836.     return(utbuf);
  837. }
  838.